package com.sali.service.data_file_uploader.refcount;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 管理引用计数
 * 若一个源文件扫描完毕了，其中的数据内容都处理完了，那么：
 *  1) 数据内容中索引到的文件便可以执行上传操作
 *  2) 源文件可以被删除
 * @author sali
 * @date 2025/3/16 21:55
 */
public class ReferenceManager {

    private static Logger log = LoggerFactory.getLogger(ReferenceManager.class);

    // 维护所有源文件的引用技术
    private static ConcurrentHashMap<String, ReferenceCounter> counterCache = new ConcurrentHashMap<>();

    // 创建源文件的引用计数
    public static void createRefCounter(String sourceFileAbsolutePath, String sourceFileId) {
        ReferenceCounter counter = new ReferenceCounter(sourceFileAbsolutePath, sourceFileId);
        counterCache.put(sourceFileId, counter);
    }

    public static void occurError(String sourceFileId) {
        if ( counterCache.containsKey(sourceFileId) ) {
            counterCache.get(sourceFileId).setOccurError(true);
        }
    }

    // 移除某个源文件的计数器
    public static void removeRefCounter(String sourceFileId) {
        if ( counterCache.containsKey(sourceFileId) ) {
            counterCache.remove(sourceFileId);
        }
    }

    // 增加源文件丢弃记录条数的计数
    public static void discardRecordInc(String sourceFileId) {
        if ( counterCache.containsKey(sourceFileId) ) {
            counterCache.get(sourceFileId).discardRecordInc();
        }
    }

    // 增加源文件输出记录条数的计数
    public static void outputRecordInc(String sourceFileId) {
        if ( counterCache.containsKey(sourceFileId) ) {
            counterCache.get(sourceFileId).outputRecordInc();
        }
    }

    // 标识当前源文件已经扫描完
    public static void scanCompleted(String sourceFileId, long recordNum) {
        if ( counterCache.containsKey(sourceFileId) ) {
            ReferenceCounter counter = counterCache.get(sourceFileId);
            counter.setReadCompleted(true);
            counter.setTotal(recordNum);
        } else {
            log.error("can not find source file: {}", sourceFileId);
        }
    }

    // 返回记录已经处理完的源文件引用计数
    public static List<ReferenceCounter> hasProcessed() {
        Iterator<Map.Entry<String, ReferenceCounter>> iterator = counterCache.entrySet().iterator();
        List<ReferenceCounter> res = new ArrayList<>();
        while ( iterator.hasNext() ) {
            ReferenceCounter counter = iterator.next().getValue();
            if ( counter.isOccurError() || counter.hasProcessed() ) {
                res.add(counter);
            }
        }
        return res;
    }

}
